筆記目錄

Skip to content

淺談 Git 資料結構

TLDR

  • .git 目錄是 Git 儲存庫的核心,刪除該目錄即等同刪除本機版控。
  • Git 物件(Blob, Tree, Commit)皆以 SHA-1 哈希值儲存於 objects 目錄中。
  • 分支與 Tag 本質上只是指向特定 Commit 物件的指標,儲存於 refs 目錄。
  • logs 目錄記錄了 HEAD 與分支的變動歷史,可透過 git reflog 進行誤操作後的還原。
  • index 檔案為二進位檔,記錄了 git add 後的暫存區快照。
  • HEAD 檔案記錄當前所在的分支或 Commit 指標。

資料夾結構解析

hooks

存放各種客製化腳本,在 Git 操作(如 commitpushmerge)的特定時機自動觸發。適用於執行自動化測試或程式碼風格檢查。

info

存放輔助性資訊,其中 exclude 檔案用於定義本機排除規則。

  • 什麼情況下會遇到這個問題:當開發者需要排除特定檔案,但該規則不應被納入團隊版控時,應使用 info/exclude 而非 .gitignore

logs

記錄引用(如 branch、HEAD)的更新歷史,用於追蹤變更紀錄。

  • 什麼情況下會遇到這個問題:當執行 git reset --hardgit rebase -i 導致 Commit 遺失時,可透過 git reflog 查詢 logs/HEAD 內容並進行還原。

objects

儲存所有 Git 資料物件(Blob, Tree, Commit)。

  • 結構:以 SHA-1 哈希值的前兩個字元為目錄,後 38 個字元為檔名。
  • 物件類型
    • Blob 物件:儲存檔案的實際內容。
    • Tree 物件:儲存目錄結構與檔案的 SHA-1 對應關係。
    • Commit 物件:儲存提交資訊(包含 Tree 的 SHA-1、父節點 SHA-1、作者與訊息)。

refs

儲存分支與 Tag 的指標,內容為對應的 Commit HASH 值。

  • heads:存放本機分支。
  • remotes:存放遠端分支。
  • tags:存放 Tag 名稱。

檔案結構解析

COMMIT_EDITMSG

記錄上一次 Commit 的訊息內容,供 git commit --amend 或解衝突時編輯使用。

config

儲存該儲存庫的專屬設定,類似於全域的 .gitconfig

index

記錄最新一次 Commit 後的檔案快照,以及 git add 加入的檔案資訊,為二進位檔案。

儲存當前檢出的分支名稱或 Commit HASH。若指向分支,內容格式為 ref: refs/heads/分支名稱

ORIG_HEAD

記錄進行破壞性操作(如 git resetgit merge)之前的 HEAD 狀態,提供復原路徑。

FETCH_HEAD

標註每次 git fetch 的紀錄。

  • 什麼情況下會遇到這個問題:當執行 git fetch 後,可透過此檔案查看遠端分支的最新狀態。格式範例如下:
text
3b3a827b86d264f9c81bc77ef6e0e3df5e302ae8 not-for-merge branch 'main' of http://127.0.0.1/wing/Project

關於分支的本質

由 Git 的資料結構可知,分支與 Tag 僅是指向特定 Commit 物件的指標。分支會隨每次 Commit 更新,而 Tag 則指向固定的歷史座標。透過追溯 Commit 物件中的父節點資訊,Git 得以構建出完整的歷史版本圖。

TIP

若使用 git reset --hard 刪除了 Commit 記錄,這些節點並不會立即從 objects 資料夾中消失,仍可透過 git reflog 找回。

異動歷程

  • 2024-07-31 初版文件建立。
  • 2024-09-20 儲存庫根目錄底下的「.gitconfig」無法生效,所以移除可作為版控的相關描述。